/******************************************************************************
 Winbond Electronics Corporation
 Verilog Simulation for W25X80 series Serial Flash Memory

 V0.13 Beta

 Copyright (c) 2001-2006 Winbond Electronics Corporation
 All Rights Reserved.


 Notes:
 This simulation does not support the following commands and functions:
   	HOLDn pin is not supported.



 Versions:
	7/6/2005	 Initial Version
	7/23/2005	 Timing Updates
	6/3/2006	 Model Updates (write_enable, erase size, HOLDn input)
	1/3/2007     Update Model to compile with ModelSim

******************************************************************************/

`timescale	1ps/1ps

module W25X80 (CSn, CLK, DIO, DO, WPn, HOLDn);
input CSn, CLK;
inout DIO;
input WPn;
input HOLDn;
output DO;

parameter NUM_PAGES = 4096;
parameter PAGESIZE  = 256;
parameter SECTORSIZE = 4096;
parameter BLOCKSIZE = 65536;
parameter MANUFACTURER = 8'hEF;
parameter DEVICE_ID	= 8'h13;
parameter JEDEC_ID_HI = 8'h30;
parameter JEDEC_ID_LO = 8'h14;
parameter ADDRESS_MASK = (NUM_PAGES * PAGESIZE) - 1;		// Note that NUM_PAGES must be a power of 2 for this simulation to work properly.
//`define MEM_FILENAME "M25P80_data.mif"						// Memory contents file(s)
parameter MEM_FILENAME ="M25P80_data.mif";

// The following registers define the main memory spaces of the
// device.
//

reg [7:0] memory [NUM_PAGES * PAGESIZE - 1:0];	// Flash memory array

reg [7:0] status_reg;				// Status Register
reg [7:0] status_reg_shadow;			// Status Register Shadow Register
reg [23:0] byte_address;				// Page address used for writing and reading

reg flag_prog_page;         			// Flag used to start the program process for sram 0
reg flag_erase_sector;				// Flag used to erase a sector
reg flag_erase_block;				// Flag used to erase a block
reg flag_erase_bulk;				// Flag used to erase the chip
reg flag_power_up_exec;
reg flag_power_down;
reg flag_power_up_sig_read;
reg flag_write_status_reg;
reg flag_slow_read_reg;
wire flag_slow_read = flag_slow_read_reg;


reg timing_error;					// Register for identifying timing errors when they occur

reg [7:0] in_byte;					// These two variables are used for debug purposes.
reg [7:0] out_byte;

// Logic output for DO pin.
//
reg DO_Reg, DO_Enable;
bufif1(DO,DO_Reg,DO_Enable);

// Logic output for DIO pin.
// 
reg DIO_Reg, DIO_Enable_reg;
wire DIO_Enable = DIO_Enable_reg;


reg RBn_Reg;						// Flag for Ready/Busy indicator

// The following are working variables for the simulation program
//

reg [7:0]  cmd_byte;
reg [7:0]  null;
reg [7:0]  temp;

integer    x;
integer	 fileno;
integer	 bytes_written;
reg [15:0] file_sector;
reg [15:0] file_length;


// The following macro's define the supported commands in this
// Simulation
//

`define CMD_WRITE_DISABLE 			8'h04
`define CMD_WRITE_ENABLE  			8'h06
`define CMD_READ_STATUS				8'h05
`define CMD_WRITE_STATUS				8'h01
`define CMD_READ_DATA				8'h03
`define CMD_READ_DATA_FAST			8'h0b
`define CMD_READ_DATA_FAST_DUAL		8'h3b
`define CMD_PAGE_PROGRAM				8'h02
`define CMD_BLOCK_ERASE				8'hD8
`define CMD_SECTOR_ERASE				8'h20
`define CMD_BULK_ERASE				8'hC7
`define CMD_DEEP_POWERDOWN			8'hB9
`define CMD_READ_SIGNATURE			8'hAB
`define CMD_READ_ID					8'h90
`define CMD_READ_JEDEC_ID			8'h9f

// Status register definitions
//

`define STATUS_SRP					8'h80
`define STATUS_TB					8'h20
`define STATUS_BP2					8'h10
`define STATUS_BP1					8'h08
`define STATUS_BP0	   				8'h04
`define STATUS_WEL		 			8'h02
`define STATUS_WIP	 				8'h01

`define SRP	7
`define TB	5
`define BP2	4
`define BP1	3
`define BP0	2
`define WEL	1
`define WIP	0

specify

// CSn timing checks

specparam	tSLCH = 5;					
$setup(negedge CSn, posedge CLK, tSLCH, timing_error); 

specparam tCHSL = 5;					
$setup(posedge CLK, negedge CSn, tCHSL, timing_error);

specparam	tSHSL = 100;					
$width(posedge CSn, tSHSL, 0, timing_error);

specparam tCHSH = 8;
$setup(posedge CLK, posedge CSn, tCHSH, timing_error);

specparam tSHCH = 5;
$setup(posedge CSn, posedge CLK, tSHCH, timing_error);


// CLK timing checks

specparam	tCYC = 14;				// Minimum CLK period for all instructions but READ_PAGE
specparam	tCLH  = 7;				// Minimum CLK high time for all instructions but READ_PAGE
specparam tCLL  = 7;		        	// Minimum CLK low time for all instructions but READ_PAGE
$period(posedge CLK &&& (~flag_slow_read), tCYC, timing_error);
$width(posedge CLK &&& (~flag_slow_read), tCLH, 0, timing_error);
$width(negedge CLK &&& (~flag_slow_read), tCLL, 0, timing_error);


specparam tCYCR = 30;				// Minimum CLK period READ_PAGE
specparam	tCRLH  = 8;				// Minimum CLK high time READ_PAGE
specparam tCRLL  = 8;		        	// Minimum CLK low time READ_PAGE
$period(posedge CLK &&& (flag_slow_read), tCYCR, timing_error);
$width(posedge CLK &&& (flag_slow_read), tCRLH, 0, timing_error);
$width(negedge CLK &&& (flag_slow_read), tCRLL, 0, timing_error);


// DIO timing checks

specparam	tDVCH = 2;				// DIO Data setup time
specparam	tCHDX = 5;                   	// DIO Data hold time

// Make sure to turn off DIO input timing checks when outputing data in dual output mode.

$setup(DIO, posedge CLK &&& (~DIO_Enable), tDVCH, timing_error);
$hold(posedge CLK, DIO &&& (~DIO_Enable), tCHDX, timing_error);

// WPn timing checks

specparam tWHSL = 20;
specparam tSHWL = 100;

$setup(posedge WPn, negedge CSn, tWHSL, timing_error);
$setup(posedge CSn, negedge WPn, tSHWL, timing_error);

endspecify


parameter tCLQV = 	7;				// Time to DO output valid.
parameter	tSHQZ = 7;				// Data output disable time.
//parameter	tW =    10000000;			// Write Status Register Write Time
parameter	tW =    100;
parameter tRES1 = 3000;				// Release from power down time 1
parameter	tRES2 = 1800;			     // Release from power down time 2
parameter	tDP =   3000;				// Time for device to enter deep power down.
parameter tBP1 =  0;			// Time for Byte Programming
parameter tBP6N = 0;				// Time for each additional byte
//parameter tBP1 =  100000;			// Time for Byte Programming
//parameter tBP6N = 6000;				// Time for each additional byte
//parameter	tPP =   1500000;			// Page Program Time
parameter	tPP =   1500;			// Page Program Time
//parameter	tSE =   150000000;			// Sector Erase Time.
parameter	tSE =   1500;			// Sector Erase Time.
parameter tBE =   1000000000;			// Block Erase Time.
parameter	tCE_10 = 1000000000;		// Chip Erase Time. This constant should be repeated 10 times.

/******************************************************************************
The following code is the initialization code run at the beginning of the
simulation.
******************************************************************************/
initial
begin :initialization

	DIO_Enable_reg = 1'b0;					// Tri-state DIO Output
	DIO_Reg = 1'bz;
	DO_Enable = 1'b0;					// Tri-state DO Output.
	DO_Reg = 1'b0;						// DO pin is low
	status_reg = 8'b0;					// Status register default value.
	RBn_Reg = 1'b1;					// Device is Ready
	flag_prog_page = 0;
	flag_erase_sector = 0;
	flag_erase_bulk = 0;
	flag_power_down = 0;
	flag_power_up_exec = 0;
	flag_power_up_sig_read = 0;
	flag_write_status_reg = 0;
	flag_slow_read_reg = 1'b0;				// Flag for standard read command....i.e. different timings
	timing_error = 0;
	cmd_byte = 0;
	null = 0;
	in_byte = 0;
	out_byte = 0;

	
	// Erase memory array to FFh state.
	for(x = 0; x < NUM_PAGES * PAGESIZE; x=x+1)
		memory[x] = 8'hff;

	$readmemh(MEM_FILENAME,memory);

end

/******************************************************************************
The following continuous assignment statement assigns the DIO_Reg register to the 
DIO inout wire.

******************************************************************************/

assign DIO = DIO_Enable ? DIO_Reg : 1'bz;

/******************************************************************************
The following routine occurs when CSn goes low.

The following routine reads the opcode in from the SPI port and starts command
execution. All commands execute the following flow:

Command Dispatch ==> Command Protocol Handler ==> Command State Machine (if necessary)

Whenever CSn goes high, the Command Dispatch and Command Protocol Handler functions
stop execution.  The Individual Command State Machines continue to run until
completion, regardless of the state of CSn.

******************************************************************************/

always @(negedge CSn)				// When CSn goes low, device becomes active
begin :read_opcode

	input_byte(cmd_byte);			// Read Opcode from SPI Port

	case (cmd_byte)				// Now dispatch the correct function

// Status Register commands

		`CMD_WRITE_ENABLE :
		begin
			if(!flag_power_down)	
				status_reg[`WEL] = 1;
	   	end
	   	`CMD_WRITE_DISABLE :
	   	begin
	   		if(!flag_power_down)
				status_reg[`WEL] = 0;
	   	end

		`CMD_DEEP_POWERDOWN :
		begin
            	if(!status_reg[`WIP] && !flag_power_down)
		  	begin
				flag_power_down = 1;
				@(posedge CLK);
				flag_power_down = 0;
			end
		end

		`CMD_READ_SIGNATURE :
		begin
           	if(!status_reg[`WIP])
           	begin
           		flag_power_up_exec = 1;
           		input_byte(null);
           		input_byte(null);
           		input_byte(null);
            		forever
           		begin
           			output_byte(DEVICE_ID);
           			flag_power_up_sig_read = 1;
           		end
           	end
		end

		`CMD_READ_JEDEC_ID :
		begin
           	if(!status_reg[`WIP] && !flag_power_down)
           	begin
				output_byte(MANUFACTURER);
           		output_byte(JEDEC_ID_HI);
				output_byte(JEDEC_ID_LO);
           	end
		end

		`CMD_READ_ID :
		begin
           	if(!status_reg[`WIP] && !flag_power_down)
           	begin
            	input_byte(byte_address[23:16]);
				input_byte(byte_address[15:8]);
				input_byte(byte_address[7:0]);
				forever
           		begin
           			if(byte_address[0])
           			begin
           				output_byte(DEVICE_ID);
           				output_byte(MANUFACTURER);
           			end
           			else
           			begin
           				output_byte(MANUFACTURER);
           				output_byte(DEVICE_ID);
           			end
           		end
           	end
		end


		`CMD_READ_STATUS :
		begin
			if(!flag_power_down)
			begin
				forever
				begin
					output_byte(status_reg);
				end
			end
		end

		`CMD_WRITE_STATUS :
		begin
	        	if(!status_reg[`WIP] && status_reg[`WEL] && !flag_power_down)
			begin
				case ({WPn,status_reg[`SRP]})
					2'b00, 2'b10, 2'b11 :
					begin
		 				input_byte(status_reg_shadow);
 						status_reg_shadow = status_reg_shadow & 8'hBC;
 						flag_write_status_reg = 1;
					end
				endcase
     		end
		end

// Write Page Commands

		`CMD_PAGE_PROGRAM :
		begin
			if(status_reg[`WEL] && !flag_power_down)
				write_page;
		end

// Erase Commands

		`CMD_SECTOR_ERASE :
		begin
			if(status_reg[`WEL] && !flag_power_down)
			begin
				input_byte(byte_address[23:16]);
				input_byte(byte_address[15:8]);
				input_byte(byte_address[7:0]);
				if(!write_protected(byte_address))
				begin
					flag_erase_sector = 1;
					@(posedge CLK);				// If an extra clock comes before CSn goes high, kill command.
					flag_erase_sector = 0;
				end
			end
		end

		`CMD_BLOCK_ERASE :
		begin
			if(status_reg[`WEL] && !flag_power_down)
			begin
				input_byte(byte_address[23:16]);
				input_byte(byte_address[15:8]);
				input_byte(byte_address[7:0]);
				if(!write_protected(byte_address))
				begin
					flag_erase_block = 1;
					@(posedge CLK);				// If an extra clock comes before CSn goes high, kill command.
					flag_erase_block = 0;
				end
			end
		end


		`CMD_BULK_ERASE :
		begin
			if(status_reg[`WEL] && !flag_power_down)
			begin
				case ({status_reg[`BP0],status_reg[`BP1]})
					2'b00 :
					begin
						flag_erase_bulk = 1;
						@(posedge CLK);
						flag_erase_bulk = 0;
					end
				endcase


				end
		end

// Read Page Commands

		`CMD_READ_DATA :
		begin
			if(!flag_power_down)
			begin
				flag_slow_read_reg = 1'b1;
				read_page(0);
			end
		end


		`CMD_READ_DATA_FAST :
		begin
			if(!flag_power_down)
				read_page(1);
		end

		`CMD_READ_DATA_FAST_DUAL :
		begin
			if(!flag_power_down)
				read_page(2);
		end

		default :
		begin
			$display("Invalid Opcode. (%x)",cmd_byte);
			$stop;
		end
	endcase
end


/******************************************************************************
 The following routine occurs when CSn goes high.  In the case, all communications
 activities inside the chip must halt. Transfer and Program/Erase conditions
 will continue.
******************************************************************************/

always @(posedge CSn)		   		// When CSn goes high, device becomes in-active
begin :disable_interface
	#tSHQZ						// Data-output disable time
	DO_Enable = 1'b0;				// Tri-state DO Output.
	DIO_Enable_reg = 1'b0;				// Tri-state DIO output.
	flag_slow_read_reg = 1'b0;			// Initiate normal timing checks

	disable input_byte;
	disable output_byte;
	disable read_opcode;
	disable write_page;
	disable read_page;
end


/******************************************************************************
 GENERAL PURPOSE SUBROUTINES
******************************************************************************/

/******************************************************************************
 The following routine will input 1 byte from the SPI DIO pin and place
 the results in the input_data register.
******************************************************************************/

task input_byte;
output [7:0] input_data;
integer x;
begin
	for(x = 7; x >= 0; x=x-1)
	begin
	   	@(posedge CLK);
          input_data[x] = DIO;
     end
	in_byte = input_data;
end
endtask

/******************************************************************************
 The following routine will output 1 byte to the DO pin.
******************************************************************************/

task output_byte;
input [7:0] output_data;
integer x;
begin
	out_byte = output_data;
	for(x = 7; x >= 0; x=x-1)
		begin
			@(negedge CLK);
			if(DO_Enable == 1'b0)					// If the bus is not enabled, enable it now.
				DO_Enable = 1'b1;
   	        	#tCLQV DO_Reg = output_data[x];
	     end
end
endtask

/******************************************************************************
 The following routine will output 1 byte to the DO and DIO pin.
******************************************************************************/

task output_byte_dual;
input [7:0] output_data;
integer x;
begin
	out_byte = output_data;
	for(x = 7; x >= 0; x=x-2)
		begin
			@(negedge CLK);
			if(DO_Enable == 1'b0)					// If the bus is not enabled, enable it now.
				DO_Enable = 1'b1;
			if(DIO_Enable_reg== 1'b0)
				DIO_Enable_reg = 1'b1;
			#tCLQV DIO_Reg = output_data[x-1];
   	        	DO_Reg = output_data[x];
	     end
end
endtask


/******************************************************************************
 The following function returns whether or not the current page is write
 protected.
******************************************************************************/

function write_protected;
input [23:0] byte_address;
begin

	casez ({status_reg[`TB],status_reg[`BP2],status_reg[`BP1],status_reg[`BP0]})
		4'b?000 :
			write_protected = 1'b0;
		4'b0001 :
		begin
			if(byte_address >= (NUM_PAGES * PAGESIZE * 15 / 16))
				write_protected = 1'b1;
			else
				write_protected = 1'b0;
		end
		4'b0010 :
		begin
			if(byte_address >= (NUM_PAGES * PAGESIZE * 7 / 8))
				write_protected = 1'b1;
			else
				write_protected = 1'b0;
		end
		4'b0011 :
		begin
			if(byte_address >= (NUM_PAGES * PAGESIZE * 3 / 4))
				write_protected = 1'b1;
			else
				write_protected = 1'b0;
		end
		4'b0100 :
		begin
			if(byte_address >= (NUM_PAGES * PAGESIZE * 1 / 2))
				write_protected = 1'b1;
			else
				write_protected = 1'b0;
		end

		4'b1001 :
		begin
			if(byte_address < (NUM_PAGES * PAGESIZE * 1 / 16))
				write_protected = 1'b1;
			else
				write_protected = 1'b0;
		end
		4'b1010 :
		begin
			if(byte_address < (NUM_PAGES * PAGESIZE * 1 / 8))
				write_protected = 1'b1;
			else
				write_protected = 1'b0;
		end
		4'b1011 :
		begin
			if(byte_address < (NUM_PAGES * PAGESIZE * 1 / 4))
				write_protected = 1'b1;
			else
				write_protected = 1'b0;
		end
		4'b1100 :
		begin
			if(byte_address < (NUM_PAGES * PAGESIZE * 1 / 2))
				write_protected = 1'b1;
			else
				write_protected = 1'b0;
		end
		4'b?101 :
			write_protected = 1'b1;
		4'b?11? :
			write_protected = 1'b1;

	endcase
end
endfunction



/******************************************************************************
 ******************************************************************************
 ******************************************************************************
 COMMAND PROTOCOL HANDLERS

 The following functions execute the command protocol for the selected function
 before enabling the internal state machine to handle the function

 ******************************************************************************
 ******************************************************************************
 ******************************************************************************/


/******************************************************************************
 READ/WRITE PAGE PROTOCOL HANDLERS
******************************************************************************/

/******************************************************************************
 The following routine will execute the Read Page command 03h and the
 Read Page Fast command 0bh.
******************************************************************************/

task read_page;
input [1:0] fast_read;
begin

	if(!status_reg[`WIP])
	begin
		input_byte(byte_address[23:16]);	
		input_byte(byte_address[15:8]);
		input_byte(byte_address[7:0]);
		if(fast_read)
			input_byte(null);
		forever
		begin
			byte_address = byte_address & ADDRESS_MASK;
			if(fast_read == 2)
				output_byte_dual(memory[byte_address]);
			else
				output_byte(memory[byte_address]);
			byte_address = byte_address + 1;
		end
	end
end
endtask

/******************************************************************************
 The following routine will execute the Write to Page command 02h.
******************************************************************************/

task write_page;
begin
	if(!status_reg[`WIP])
	begin
		bytes_written = 0;
		input_byte(byte_address[23:16]);
		input_byte(byte_address[15:8]);
		input_byte(byte_address[7:0]);
		if(!write_protected(byte_address))
		begin
			forever
			begin
				input_byte(temp);
				memory[byte_address] = memory[byte_address] & temp;
				flag_prog_page = 1;
				bytes_written = bytes_written + 1;
				if(bytes_written > 264)
					bytes_written = 264;
				byte_address[7:0] = byte_address[7:0] + 1;
			end
		end
	end
end
endtask


/******************************************************************************
 ******************************************************************************
 ******************************************************************************
 COMMAND STATE MACHINES
 ******************************************************************************
 ******************************************************************************
 ******************************************************************************/


/******************************************************************************
 POWER UP/DOWN STATE MACHINES
******************************************************************************/

/******************************************************************************
 The following routine occurs when flag_power_up_exec goes high.
 This starts the main process for the power up process.
******************************************************************************/

always @(posedge flag_power_up_exec)

begin :power_up

	@(posedge CSn);
	if(flag_power_up_exec == 1)
	begin
		if(flag_power_up_sig_read == 1)
			#tRES2;
		else
		begin
			#tRES1;
		end

		flag_power_down = 0;
		flag_power_up_exec = 0;
		flag_power_up_sig_read = 0;
	end
end

/******************************************************************************
 The following routine occurs when flag_power_down_exec goes high.
 This starts the main process for the power down process.
******************************************************************************/

always @(posedge flag_power_down)

begin :power_down

	@(posedge CSn);
	if(flag_power_down == 1)
	begin
		#tDP;
	end
end

/******************************************************************************
 ERASE PAGE/BLOCK COMMAND STATE MACHINES
******************************************************************************/


/******************************************************************************
 The following routine occurs when flag_erase_sector goes high.
 This starts the main erase process for the defined sector.
******************************************************************************/

always @(posedge flag_erase_sector)		// When flag_erase_sector goes high, device becomes active
									// and starts erasing the sector defined by byte_address
begin :erase_sector

	@(posedge CSn);					// Wait for CSn to go high
	if(flag_erase_sector == 1)
	begin
		status_reg[`WIP] = 1;

		for(x = 0; x < SECTORSIZE; x=x+1)
			memory[(byte_address[23:12] * SECTORSIZE) + x] = 8'hff;


		#tSE;
		status_reg[`WIP] = 0;
		status_reg[`WEL] = 0;
	end
	flag_erase_sector = 0;
end

/******************************************************************************
 The following routine occurs when flag_erase_block goes high.
 This starts the main erase process for the defined block.
******************************************************************************/

always @(posedge flag_erase_block)		// When flag_erase_block goes high, device becomes active
								// and starts erasing the block defined by byte_address
begin :erase_block

	@(posedge CSn);					// Wait for CSn to go high
	if(flag_erase_block == 1)
	begin
		status_reg[`WIP] = 1;

		for(x = 0; x < BLOCKSIZE; x=x+1)
			memory[(byte_address[23:16] * BLOCKSIZE) + x] = 8'hff;


		#tBE;
		status_reg[`WIP] = 0;
		status_reg[`WEL] = 0;
	end
	flag_erase_block = 0;
end


/******************************************************************************
 The following routine occurs when flag_erase_bulk goes high.
 This starts the main erase process for the entire chip.
******************************************************************************/

always @(posedge flag_erase_bulk)	// When flag_erase_block goes high, device becomes active
									// and starts erasing the block defined by page_address
begin :erase_bulk

	@(posedge CSn);					// Wait for CSn to go high
	if(flag_erase_bulk == 1)
	begin
		status_reg[`WIP] = 1;

		for(x = 0; x < PAGESIZE * NUM_PAGES; x=x+1)
			memory[x] = 8'hff;


		#tCE_10;
		#tCE_10;
		#tCE_10;
		#tCE_10;
		#tCE_10;
		#tCE_10;
		#tCE_10;
		#tCE_10;
		#tCE_10;
		#tCE_10;

		status_reg[`WIP] = 0;
		status_reg[`WEL] = 0;
	end
	flag_erase_bulk = 0;

end

/******************************************************************************
 PROGRAMMING PAGE COMMAND STATE MACHINES
******************************************************************************/

/******************************************************************************
 The following routine occurs when flag_prog_page goes high.
 This starts the program page process.
******************************************************************************/

always @(posedge flag_prog_page)				// When flag_prog_page goes high, device becomes active
// and starts programming the page defined by page_address
begin :program_to_page

	@(posedge CSn);						// Wait for CSn to go high
	begin
		status_reg[`WIP] = 1;

		#tBP1;							// tBP1 + 6 * bytes_written microseconds
		for(x = 0; x < bytes_written; x=x+1)
			#tBP6N;

		status_reg[`WIP] = 0;
		status_reg[`WEL] = 0;
	end
	flag_prog_page = 0;
end


/******************************************************************************
 CONFIGURATION REGISTER COMMAND STATE MACHINES
******************************************************************************/

/******************************************************************************
 The following routine occurs when flag_write_status_reg goes high.
 This starts the main write status register process.
******************************************************************************/

always @(posedge flag_write_status_reg)	    		// When flag_write_stgatus_reg goes high, device becomes active
										// and starts writing the status_reg_shadow register into the
begin :write_status_reg

	@(posedge CSn);						// Wait for CSn to go high

	status_reg[`WIP] = 1;
	status_reg[`SRP] = status_reg_shadow[`SRP];
	status_reg[`BP0] = status_reg_shadow[`BP0];
	status_reg[`BP1] = status_reg_shadow[`BP1];
	status_reg[`BP2] = status_reg_shadow[`BP2];
	status_reg[`TB] = status_reg_shadow[`TB];
	#tW;
	status_reg[`WIP] = 0;
	status_reg[`WEL] = 0;
	flag_write_status_reg = 0;
end

endmodule // W25X80
